package org.zqh.ncc.thread;

import com.alibaba.fastjson.JSON;
import nccloud.open.api.auto.token.cur.utils.APICurUtils;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.stereotype.Component;
import org.zqh.ncc.config.NcConfig;
import org.zqh.ncc.config.XsToErp;
import org.zqh.ncc.ncmodel.NcBillReturn;
import org.zqh.ncc.ncmodel.XS.BillInfo;
import org.zqh.ncc.ncmodel.XS.JsonRootBean;
import org.zqh.ncc.ncmodel.XS.So_delivery;
import org.zqh.ncc.ncmodel.XS.So_delivery_b;
import org.zqh.ncc.utils.TimeUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.PriorityBlockingQueue;

/**
 * 定时扫描t_bangdan表，发现有需要推NC单据的记录，就进行处理,该线程只处理销售发货单推送NC
 */
@Component
public class XsToErpThread extends CommonThread<XsToErp> {
    volatile long beginTime = 0;
    NcConfig ncConfig;
    APICurUtils apiUtils;
    String token;

    /**
     *
     */
    public XsToErpThread(PriorityBlockingQueue<XsToErp> xsToErpQueue, @Qualifier("xsApiCurUtils") APICurUtils apiCurUtils, NcConfig ncConfig) {
        super(xsToErpQueue);
        this.apiUtils = apiCurUtils;
        this.ncConfig = ncConfig;
        apiUtils.init(ncConfig.getDx_xs_ip(), ncConfig.getDx_xs_port(), ncConfig.getDx_biz_center(), ncConfig.getDx_client_id(), ncConfig.getDx_client_secret(), ncConfig.getDx_pubKey(), ncConfig.getDx_user_name(), ncConfig.getDx_pwd());
        this.setName("xsToErpThread");


    }

    /**
     * 线程启动运行，推送状态报告
     */
    public void run() {
        while (!isStopping) {
            try {
                List<XsToErp> bdList = getXsToErpList(10);
                if (bdList.size() > 0) {
                    processList(bdList);
                    beginSleep(100);
                } else {
                    beginSleep(3000);
                }
            } catch (Exception e) {
                log.error("", e);
                beginSleep(10000);
            }
        }
        isStopped = true;
    }

    /**
     * @param bdList
     */
    private void processList(List<XsToErp> bdList) {
        beginTime = System.currentTimeMillis();
        for (XsToErp xsToErp : bdList) {
            log.debug("before xsToErp post :" + xsToErp);
            try {
                token = apiUtils.getToken();
                apiUtils.setApiUrl(ncConfig.getDx_url());
                List<String> sendJsonList = toErp(xsToErp);
                String apiRetrun;
                String sql;
                String resultToErp = "1";
                String resultMemo = "";
                for (String sendJson : sendJsonList) {
                    log.info("send: " + ncConfig.getDx_xs_ip() + ":" + ncConfig.getDx_xs_port() + " json=" + sendJson);
                    apiRetrun = apiUtils.getAPIRetrun(token, sendJson);
                    log.info((System.currentTimeMillis() - beginTime) + " ms return: " + apiRetrun);
                    NcBillReturn ncBillReturn = JSON.parseObject(apiRetrun, NcBillReturn.class);
                    if (null != ncBillReturn) {
                        if (null == ncBillReturn.getMessage())
                            ncBillReturn.setMessage("null");
                        else if (ncBillReturn.getMessage().length() > 100) {
                            ncBillReturn.setMessage(ncBillReturn.getMessage().replaceAll("'", "#"));
                            ncBillReturn.setMessage(ncBillReturn.getMessage().substring(0, 98));
                        }
                        if (!ncBillReturn.isSuccess()) {
                            resultToErp = "7";
                        }
                        resultMemo += ncBillReturn.getMessage() + "---";
                    } else {
                        resultToErp = "7";
                        resultMemo += "null---";
                    }
                }
                //2024-08-25 修复当推送多条时，如果全部都是返回null，则把状态7改为-1，意思是全部失败，而不是部分失败
                if (resultToErp.equals("7") && sendJsonList.size() == countSubstring(resultMemo,"---")) {
                    resultToErp = "-1";
                    resultMemo = resultMemo.replaceAll("---", "");
                }

                sql = "update t_bangdan set resulttime=sysdate,resultmemo='" + resultMemo + "',resulttoerp='" + resultToErp +
                        "' where vbdcode='" + xsToErp.getVbdcode() + "'";
                try {
                    jdbcTemplate.update(sql);
                } catch (Exception sqlError) {
                    log.error("sql=" + sql, sqlError);
                }
            } catch (Exception e) {
                e.printStackTrace();
                log.error("调用接口错误：", e);
            }
        }
    }

    /**
     * 先更新t_bangdan表，加上一个uuid,后面根据这个uuid进行select，更新那些需要同步推送到NC的过磅单，根据resulttoerp字段的值
     *
     * @param count 每次处理的数量
     * @return
     */
    private List<XsToErp> getXsToErpList(int count) {
        List<XsToErp> bdList = new ArrayList<>();
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        int rowCount = 0;
        String sql = "update t_bangdan set resulttoerp='2',updateuuid='" + uuid + "',duuidtime=sysdate where vbdtype='XS' and resulttoerp='0' and isfinish='1' and vdelflag='0' and rownum <= " + count;
        try {
            rowCount = jdbcTemplate.update(sql);
        } catch (Exception sqlError) {
            log.error("sql=" + sql, sqlError);
        }
        if (rowCount > 0) {
            bdList = jdbcTemplate.query("select * from v_xs_bangdan where updateuuid='" + uuid + "'", new BeanPropertyRowMapper(XsToErp.class));
            if (bdList.size() != rowCount) {
                log.warn("uuid=" + uuid + " updateCount=" + rowCount + " getCount=" + bdList.size() + ", 注意检查");
            }
        }
        return bdList;
    }

    /**
     * 从视图返回的对象，转换为json，传递给NC接口，推式生成采购订单
     *
     * @param xsToErp
     * @return
     */
    private List<String> toErp(XsToErp xsToErp) {
        List<String> erpBillList = new ArrayList<String>();

        String[] hids = xsToErp.getVerphid().split(",");
        String[] bids = xsToErp.getVerpbid().split(",");
        String[] oldNums = new String[hids.length];
        if (null == xsToErp.getOldnum() || xsToErp.getOldnum().equals("")) {
            for (int i = 0; i < hids.length; i++) {
                oldNums[i] = "0";
            }
        } else {
            oldNums = xsToErp.getOldnum().split(",");
        }
        String[] newNums = getNewNum(hids.length, oldNums, xsToErp.getNjingzhong());

        int k = 0;
        for (String hid : hids) {
            JsonRootBean jb = new JsonRootBean();
            BillInfo billInfo = new BillInfo();

            So_delivery so_delivery = new So_delivery();
            so_delivery.setCdeliveryid(hid);

            So_delivery_b so_delivery_b = new So_delivery_b();
            so_delivery_b.setCdeliverybid(bids[k]);
            so_delivery_b.setNnum(xsToErp.getNjingzhong());
            so_delivery_b.setVbdef14("" + xsToErp.getNpizhong());
            so_delivery_b.setVbdef15(TimeUtil.getStrDateFormat(xsToErp.getDintime()));

            so_delivery_b.setVbdef18(newNums[k]);

            so_delivery_b.setVbdef16("" + (xsToErp.getNpizhong() + Integer.parseInt(newNums[k])));
            so_delivery_b.setVbdef17(TimeUtil.getStrDateFormat(xsToErp.getDouttime()));

            so_delivery_b.setVbdef19(xsToErp.getVcarno());
            so_delivery_b.setVbdef20(xsToErp.getVbdcode());
            so_delivery_b.setVbdef34("" + xsToErp.getOldnum());

            billInfo.setSo_delivery(so_delivery);
            List<So_delivery_b> blist = new ArrayList<>();
            blist.add(so_delivery_b);
            billInfo.setSo_delivery_b(blist);
            List<BillInfo> billInfoList = new ArrayList<>();
            billInfoList.add(billInfo);
            jb.setBillInfo(billInfoList);

            erpBillList.add(JSON.toJSONString(jb));
            k++;
        }
        return erpBillList;
    }

    private String[] getNewNum(int hidsLen, String[] oldNums, int jinzhong) {
        String[] newNums = new String[oldNums.length];

        float totalNum = 0;
        int i = 0;
        for (String bnum : oldNums) {
            totalNum += Float.parseFloat(bnum);
        }
        for (String bnum : oldNums) {
            if (oldNums.length != hidsLen) {
                newNums[i] = "" + jinzhong;
            } else {
                newNums[i] = "" + Math.round((float) jinzhong / totalNum * Float.parseFloat(bnum));
            }
            i++;
        }
        return newNums;
    }

    public static int countSubstring(String str, String sub) {
        int count = 0;
        int index = 0;
        while ((index = str.indexOf(sub, index)) != -1) {
            index += sub.length();
            count++;
        }
        return count;
    }

    public static void main(String[] args) {
        String str = "test1 string for test test,test111,test";
        String sub = "test";
        int count = countSubstring(str, sub);
        System.out.println("Substring '" + sub + "' appears " + count + " times.");
    }

}
